import { Body, Controller, Get, Post, Res, HttpStatus, UploadedFile, UseInterceptors, HttpException, Query, Request, Response, Header, All, Inject } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { Video } from './video.entity';
import { VideoService } from './video.service';
import { InternetCelebrity } from '../internetCelebrity/internetCelebrity.entity';
import { InternetCelebrityService } from '../internetCelebrity/internetCelebrity.service';
import { Answer } from '../answer/answer.entity';
import { AnswerService } from '../answer/answer.service';
import { User } from '../user/user.entity';
import { UserService } from '../user/user.service';
import { TypeEnum, CheckEnum } from '../answer/answer.enum'
import { TypeEnum as TypeEnumPlatform } from '../platform/platform.enum';
const { VodUploadClient, VodUploadRequest } = require('vod-node-sdk');
const tencentcloud = require("tencentcloud-sdk-nodejs");
var querystring = require("querystring");
import utils from '../../common/utils'
import {
  WXAPI
} from '../../common/wx_api'
import {
  secretId,
  secretKey,
  video_SubAppId,
  video_VideoTimeout,
  video_RefererKey,
  video_SubAppId_List,
  wx_appid,
  system_wx_user,
  HOSTNAME,
} from '../../setting'
import {
  apibefore
} from '../../router'
const VodClient = tencentcloud.vod.v20180717.Client;
const crypto = require('crypto')
import { ValidTokenInterceptor } from '../../interceptor/validToken'
import { EnumIsHome, IsRewardEnum, OriginalEnum, OverseasEnum, ProfitTypeEnum, SourceEnum, VideoEnum } from './video.enum'
import { RedisInstance } from '../../common/redis';
const redis_editMedia = RedisInstance.initRedis();
const mp4tohls = 'mp4tohls:'
const pullvideo = 'pullvideo:'

import {join, resolve, extname} from 'path'
import { createWriteStream, existsSync, mkdirSync, writeFileSync, unlinkSync, fstat, readFileSync, createReadStream } from 'fs';
import { ValidRSAInterceptor } from 'src/interceptor/validRSA';
import { PlatformService } from '../platform/platform.service';
import { MultiImg } from '../multiImg/multiImg.entity';
import { TraceRelaTableService } from '../traceRelaTable/traceRelaTable.service';
import { TraceRelaTable } from '../traceRelaTable/traceRelaTable.entity';
import { AnswerInfo } from '../answerInfo/answerInfo.entity';
import { WxUserService } from '../wxUser/wxUser.service';
import { WxUser } from '../wxUser/wxUser.entity';
import { SettingService } from '../setting/setting.service';
import { SettingKeyEnum } from '../setting/setting.enum';
import { Setting } from '../setting/setting.entity';
import { UserSettingService } from '../userSetting/userSetting.service';
import { EnumInternetCelebrityGroupTypeEnum } from '../internetCelebrityGroup/internetCelebrityGroup.enum';
import { profitEnum } from '../profit/profit.enum';
import { ValidUniqueLoginInterceptor } from 'src/interceptor/validUniqueLogin';
import { WsStartGateway } from '../ws/ws.gateway';
import { Redis } from 'ioredis';
import { InjectRedis } from '@nestjs-modules/ioredis';
import { RateLimiterMemory } from 'rate-limiter-flexible';
import { RedisCacheService } from '../redisCache/redisCache.service';
import { RateLimiterService } from '../rateLimiter/rateLimiter.service';
import { video_basic } from 'src/cachekeys';
const fs = require('fs')
const path = require('path')
const request = require('request')

const clientConfig = {
  credential: {
    secretId: secretId,
    secretKey: secretKey,
  },
  region: "",
  profile: {
    httpProfile: {
      endpoint: "vod.tencentcloudapi.com",
    },
  },
};
@Controller(apibefore('/video'))
export class VideoController {

  constructor(private readonly videoService: VideoService,
    private readonly internetCelebrityService: InternetCelebrityService,
    private readonly answerService: AnswerService,
    private readonly userServices: UserService,
    private readonly platformServices: PlatformService,
    private readonly traceRelaTableServices: TraceRelaTableService,
    private readonly wxUserServices: WxUserService,
    private readonly settingServices: SettingService,
    private readonly userSettingServices: UserSettingService,
    private readonly wsStartGateway: WsStartGateway,
    @InjectRedis() private readonly redis: Redis,
    private readonly redisCacheService: RedisCacheService, 
    private readonly rateLimiter: RateLimiterService, 
  ) {
  }

  
  @Post('/push_video_updates')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  pushVideoUpdates(@Body() data) {
    if(data.video_id){
      this.wsStartGateway.postUpdateVideo(data.video_id)
    }
  }

  @Get('/refreshVideoPlayUrl')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async refreshVideoPlayUrl(@Query() params, @Request() req) {
    let findVideo = await this.videoService.findOne(params.video_id)
    if(findVideo){
      this.getPlayVideoUrl(findVideo)
      return findVideo.video_url
    }else{
      return ''
    }
  }

  @Get('/getway')
  getway(@Request() req){
    this.wsStartGateway.postUpdateNotice(req.headers.wx_user)
    return true
  }
  
  /**
   * 复制视频到全部
   * @param data 
   * @param req 
   * @returns 
   */
  @Post('/copyToAll')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async copyToAll(@Body() data, @Request() req){
    let result:any = await this.videoService.copyToAll(data.video_id)
    if(result.video_id){
      let video_id = result.video_id
      await redis_editMedia.set(pullvideo + video_id, video_id)
      return true
    }else{
      return new HttpException('复制失败', HttpStatus.INTERNAL_SERVER_ERROR)
    }
  }

  /**
   * 查询视频和图片各自数量
   * @param req 
   * @returns 
   */
  @Get('/getVideoAndImageCount_auth')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async getVideoAndImageCount_Auth(@Request() req) {
    let token: number = req.headers.token
    //查询用户的wx_user
    let findUser:User = await this.userServices.findOne(token)
    if(!findUser){
      return new HttpException('用户不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    return this.videoService.getVideoAndImageCount(findUser.wx_user)
  }
  
  @Get('/DescribeMediaInfos')
  async DescribeMediaInfos(@Query() params){
    console.log(params)
    let videos = await this.videoService.findAllGlobal()
    return await utils.DescribeMediaInfos(videos.map(e => e.video_id), Number('1500018557'))
  }
  
  /**
   * 替换视频
   * @param params
   * @returns
   */
  @Post('/replaceMedia')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async replaceMedia(@Body() data, @Request() req) {
    let token: number = req.headers.token
    //查询用户的wx_user
    let findUser:User = await this.userServices.findOne(token)
    if(!findUser){
      return new HttpException('用户不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    //查找视频
    let findVideo = await this.videoService.findOne(data.id)
    if(!findVideo){
      return new HttpException('视频不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }

    let url = data.url
    let callback = async(err, result) => {
      let video_id_old = findVideo.video_id
      let processKey = 'ProcessVideo_CutVideo:' + video_id_old
      this.deleteVideo(data.coverId,() => {},() => {})
      this.deleteVideo(video_id_old,() => {},() => {})
      if(!err){
        if(result.video_cover){
          findVideo.video_cover = result.video_cover
        }
        if(result.video_id && result.video_url){
          findVideo.video_id = result.video_id
          findVideo.video_url = result.video_url
          await this.videoService.update(findVideo)
        }
        await redis_editMedia.set(processKey, JSON.stringify({
          process:100,
          video_id:findVideo.video_id,
          video_url:findVideo.video_url,
          video_cover: findVideo.video_cover
        }))
      }
      await redis_editMedia.expire(processKey,10)

      await redis_editMedia.set(mp4tohls + findVideo.id, findVideo.id)
    }

    try{
      let result = await this.videoService.updatePlayVideoUrlToMp4(findVideo.id, findVideo.video_url_source)
      if(result.affected > 0){
        return await utils.pullMediaAndUpload(redis_editMedia, findVideo.video_id, data.url, data.cover, callback, Number(video_SubAppId))
      }else{
        return new HttpException('修改原始地址失败:', HttpStatus.INTERNAL_SERVER_ERROR)
      }
    }catch(err) {
      return new HttpException('修改原始地址失败', HttpStatus.INTERNAL_SERVER_ERROR)
    }

  }

  
  @Post('/changeIcGroup')
  async changeIcGroup(@Body() videoParam: { id: number; ic_group: number  }) {
    let err = await this.videoService.updateIcGroup(videoParam.id,videoParam.ic_group)
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return true
    }
  }
  
  /**
   * 进入网红主页
   * @param videoParam 
   * @returns 
   */
  @Post('/changeInIc')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async changeInIc(@Body() videoParam: { id: number; in_ic: number  }) {
    if(Number(videoParam.in_ic) !== 0 && Number(videoParam.in_ic) !== 1) {
      return new HttpException('传参有误', HttpStatus.INTERNAL_SERVER_ERROR)
    }
    let err = await this.videoService.updateInIc(videoParam.id,videoParam.in_ic)
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return true
    }
  }

  /**
   * 视频/图片审核
   * @param videoParam 
   * @returns 
   */
  @Post('/changeCheck_auth')
  async changeCheck_auth(@Body() videoParam: { id: number; check: number, isic?: any  }) {
    if(Number(videoParam.check) !== 0 && Number(videoParam.check) !== 1) {
      return new HttpException('传参有误', HttpStatus.INTERNAL_SERVER_ERROR)
    }
    let err = await this.videoService.updateCheck(videoParam.id,videoParam.check, videoParam.isic == 1)
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return true
    }
  }

  /**
   * 视频/图片审核
   * @param videoParam 
   * @returns 
   */
  @Post('/changeCheck')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async changeCheck(@Body() videoParam: { id: number; check: number, isic?: any  }) {
    if(Number(videoParam.check) !== 0 && Number(videoParam.check) !== 1) {
      return new HttpException('传参有误', HttpStatus.INTERNAL_SERVER_ERROR)
    }
    let err = await this.videoService.updateCheckManager(videoParam.id,videoParam.check, videoParam.isic == 1)
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return true
    }
  }

  @Post('/changeCheckText')
  async changeCheckText(@Body() videoParam: { id: number; check_text: number  }) {
    let result = await this.videoService.updateCheckText(videoParam.id,videoParam.check_text)
    if(result){
      return new HttpException(result, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return true
    }
  }


  @Get('/getSign')
  async getSign(@Query() params){
    console.log(params,'ss')
    // await utils.DescribeMediaInfos(['3270835009530479093'], Number(video_SubAppId))
    // 确定 app 的云 API 密钥
    var secret_id = secretId
    var secret_key = secretKey
    // 确定签名的当前时间和失效时间
    var current:number = (new Date()).getTime()
    var expired = current + 1000 * 60 * 60 * 24;  // 签名有效期：1天
    // 向参数列表填入参数
    var arg_list:any = {
      secretId : secret_id,
      currentTimeStamp : current,
      expireTime : expired,
      random : Math.round(Math.random() * Math.pow(2, 32))
    }
    //是否上传到子应用里
    if(params.app && video_SubAppId_List[params.app]){
      arg_list.vodSubAppId = video_SubAppId_List[params.app]
    }else{
      arg_list.vodSubAppId = video_SubAppId
    }
    // 计算签名
    var orignal = querystring.stringify(arg_list);
    var orignal_buffer = new Buffer(orignal, "utf8");
    var hmac = crypto.createHmac("sha1", secret_key);
    var hmac_buffer = hmac.update(orignal_buffer).digest();
    var signature = Buffer.concat([hmac_buffer, orignal_buffer]).toString("base64");
    return signature
  }

  @Get('/getSign_Answer')
  async getSign_Answer(){
    return await this.getSign({app:'answer'})
  }

  @Post('/editMedia')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async editMedia(@Body() data, @Request() req){
    let wx_user = req.headers.token
    //查询当前用户微信id
    let findUser = await this.userServices.findOne(wx_user)
    if(!findUser){
      return new HttpException('用户不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    //查找视频
    let findVideo = await this.videoService.findOne(data.id)
    if(!findVideo){
      return new HttpException('视频不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    let callback = async(err, result) => {
      if(!err){
        let video_id_old = findVideo.video_id
        if(result.video_cover){
          findVideo.video_cover = result.video_cover
        }
        if(result.video_id && result.video_url){
          findVideo.video_id = result.video_id
          findVideo.video_url = result.video_url
          await this.videoService.update(findVideo)
        }
        let processKey = 'ProcessVideo_CutVideo:' + video_id_old
        await redis_editMedia.set(processKey, JSON.stringify({
          process:100,
          video_id:findVideo.video_id,
          video_url:findVideo.video_url,
          video_cover: findVideo.video_cover
        }))
        await redis_editMedia.expire(processKey,10)
        await redis_editMedia.set(mp4tohls + findVideo.id, findVideo.id)
      }
    }
    //先修改播放地址为原始地址
    try{
      let result = await this.videoService.updatePlayVideoUrlToMp4(findVideo.id, findVideo.video_url_source)
      if(result.affected > 0){
        return await utils.editMedia(redis_editMedia, findVideo.video_id, data.StartTimeOffset, data.EndTimeOffset, callback, Number(video_SubAppId))
      }else{
        return new HttpException('修改原始地址失败:', HttpStatus.INTERNAL_SERVER_ERROR)
      }
    }catch(err) {
      return new HttpException('修改原始地址失败', HttpStatus.INTERNAL_SERVER_ERROR)
    }
  }

  @Get('/findEditMediaProcess')
  async findEditMediaProcess(@Query() params, @Request() req){
    let wx_user = req.headers.token
    //查询当前用户微信id
    let findUser = await this.userServices.findOne(wx_user)
    if(!findUser){
      return new HttpException('用户不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    let processKey = 'ProcessVideo_CutVideo:' + params.video_id
    let process:any = await redis_editMedia.get(processKey)
    if(process){
      process = JSON.parse(process)
    }else{
      process = {process:''}
    }

    if(process.video_url){
      this.getPlayVideoUrl(process)
    }
    if(Number(process.process) == 100){
      await redis_editMedia.expire(processKey,0)
    }else{
      await redis_editMedia.expire(processKey,10)
    }
    return process
  }


  /**
   * 视频库上传
   * @param videoParam
   * @returns
   */
  @Post('/create_video_library')
  async create_video_library(@Body() videoParam: { fileType: string, token: number, title: string; desc: string, video_url: string, video_ratio?: string, video_cover?: string, ic_name?: string, ic_group?: number, fileId?: string }, @Request() req) {
    let video = new Video();
    video.title = videoParam.title;
    video.desc = videoParam.desc;
    video.video_ratio = videoParam.video_ratio
    video.create_time = new Date();
    video.update_time = new Date();
    video.video_id = videoParam.fileId;
    video.video_url = videoParam.video_url;
    video.video_cover = videoParam.video_cover;
    video.check = 1
    video.source = SourceEnum.background
    video.original = OriginalEnum.yes
    video.check_time = new Date();
    video.ic_group = videoParam.ic_group
    if(videoParam.fileType === 'img'){
      video.type = VideoEnum.image
    }else if(videoParam.fileType === 'video'){
      video.type = VideoEnum.video
    }
    let token = req.headers.token
    //查询当前用户微信id
    let findUser = await this.userServices.findOne(token)
    if(!findUser){
      return new HttpException('用户不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    video.wx_user = findUser.wx_user
    return await this.videoService.create_video_library(video)
  }

  

  /**
   * 视频库上传
   * @param videoParam
   * @returns
   */
   @Post('/upload_video_robot')
   @UseInterceptors(ValidRSAInterceptor)
   @UseInterceptors(ValidTokenInterceptor)
   async upload_video_robot(@Body() videoParam: { check:number, fileType: string, token: number, title: string; desc: string, video_url: string, video_ratio?: string, video_cover?: string, ic_name?: string, ic_group?: number, fileId?: string }, @Request() req) {
     let video = new Video();
     video.title = videoParam.title;
     video.desc = videoParam.desc;
     video.video_ratio = videoParam.video_ratio
     video.create_time = new Date();
     video.update_time = new Date();
     video.video_id = videoParam.fileId;
     video.video_url = videoParam.video_url;
     video.video_cover = videoParam.video_cover;
     video.check = videoParam.check
     video.source = SourceEnum.robot
     video.original = OriginalEnum.yes
     video.check_time = new Date();
     video.ic_group = videoParam.ic_group
     video.wx_user = req.headers.wx_user
     if(videoParam.fileType === 'img'){
       video.type = VideoEnum.image
     }else if(videoParam.fileType === 'video'){
       video.type = VideoEnum.video
     }
     return await this.videoService.create_video_library(video)
   }

   
  /**
   * 视频库修改
   * @param videoParam
   * @returns
   */
  @Post('/update_video_ic')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async update_video_ic(@Body() videoParam: { id: number; title: string; desc: string, video_url: string, video_ratio?: string, video_cover?: string, ic_name?: string, ic_group?: number, fileId?: string  }) {
    // 获取上传成功后的信息
    let video = new Video();
    video.id = videoParam.id;
    video.title = videoParam.title;
    video.desc = videoParam.desc;
    video.update_time = new Date();
    video.ic_group = videoParam.ic_group || null
    if(videoParam.fileId){
      video.video_id = videoParam.fileId;
      video.video_url = videoParam.video_url;
      video.video_cover = videoParam.video_cover
      video.video_ratio = videoParam.video_ratio
    }
    //没有网红则变成提问
    if(!video.ic_group){
      video.original = OriginalEnum.no
    }else{
      video.original = OriginalEnum.yes
    }

    let findOne = await this.videoService.findOne(videoParam.id)
    if(findOne){
      video.wx_user = findOne.wx_user
      let update_video_library = async (resolve, reject) => {
        let err = await this.videoService.update_video_ic(video)
        if(err){
          reject(new HttpException(err, HttpStatus.OK))
        }else{
          resolve(true)
        }
      }
      return new Promise((resolve, reject) => {
        if(videoParam.fileId){
          this.deleteVideo(findOne.video_id,async () => {
            update_video_library(resolve, reject)
          },(err) => {
            reject(new HttpException(err, HttpStatus.OK))
          })
        }else{
          update_video_library(resolve, reject)
        }
      })
    }else{
      return new HttpException('视频不存在', HttpStatus.OK)
    }
  }

  /**
   * 视频库修改
   * @param videoParam
   * @returns
   */
  @Post('/update_video_library')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async update_video_library(@Body() videoParam: { id: number; title: string; desc: string, video_url: string, video_ratio?: string, video_cover?: string, ic_name?: string, ic_group?: number, fileId?: string  }) {
    // 获取上传成功后的信息
    let video = new Video();
    video.id = videoParam.id;
    video.title = videoParam.title;
    video.desc = videoParam.desc;
    video.update_time = new Date();
    video.ic_group = videoParam.ic_group || null
    if(videoParam.fileId){
      video.video_id = videoParam.fileId;
      video.video_url = videoParam.video_url;
      video.video_cover = videoParam.video_cover
      video.video_ratio = videoParam.video_ratio
    }
    //没有网红则变成提问
    if(!video.ic_group){
      video.original = OriginalEnum.no
    }else{
      video.original = OriginalEnum.yes
    }

    let findOne = await this.videoService.findOne(videoParam.id)
    if(findOne){
      video.wx_user = findOne.wx_user
      let update_video_library = async (resolve, reject) => {
        let err = await this.videoService.update_video_library(video)
        if(err){
          reject(new HttpException(err, HttpStatus.OK))
        }else{
          resolve(true)
        }
      }
      return new Promise((resolve, reject) => {
        if(videoParam.fileId){
          this.deleteVideo(findOne.video_id,async () => {
            update_video_library(resolve, reject)
          },(err) => {
            reject(new HttpException(err, HttpStatus.OK))
          })
        }else{
          update_video_library(resolve, reject)
        }
      })
    }else{
      return new HttpException('视频不存在', HttpStatus.OK)
    }
  }

  /**
   * 后台管理库上传
   * @param videoParam
   * @returns
   */
  @Post('/create')
  async create(@Body() videoParam: { title: string; desc: string, video_url: string, video_ratio?: string, video_cover?: string, ic_name?: string, ic_group?: number, fileId?: string }) {
    let video = new Video();
    video.title = videoParam.title;
    video.desc = videoParam.desc;
    video.video_ratio = videoParam.video_ratio
    video.create_time = new Date();
    video.update_time = new Date();
    video.video_id = videoParam.fileId;
    video.video_url = videoParam.video_url;
    video.video_cover = videoParam.video_cover;
    video.check = 1

    if(videoParam.ic_group){
      video.ic_group = videoParam.ic_group
    }else{
      //查询网红是否存在
      const ic_name = videoParam.ic_name || ''
      let ic_info:any = await this.internetCelebrityService.findOne_ByName(ic_name)
      if(!ic_info){
        let addIc = new InternetCelebrity()
        addIc.name = ic_name
        ic_info = await this.internetCelebrityService.create(addIc)
      }
      if(ic_info){
        video.ic_group = ic_info.id
      }
    }
    return await this.videoService.create(video)
  }

  /**
   * 后台管理库修改
   * @param videoParam
   * @returns
   */
  @Post('/update')
  async update(@Body() videoParam: { id: number; title: string; desc: string, video_url: string, video_ratio?: string, video_cover?: string, ic_name?: string, ic_group?: number, fileId?: string  }) {
      // 获取上传成功后的信息
      let video = new Video();
      video.id = videoParam.id;
      video.title = videoParam.title;
      video.desc = videoParam.desc;
      video.update_time = new Date();
      if(videoParam.fileId){
        video.video_id = videoParam.fileId;
        video.video_url = videoParam.video_url;
        video.video_cover = videoParam.video_cover
        video.video_ratio = videoParam.video_ratio
      }

      let findOne = await this.videoService.findOne(videoParam.id)
      return new Promise((resolve, reject) => {
        this.deleteVideo(findOne.video_id,async () => {
          if(videoParam.ic_group){
            video.ic_group = videoParam.ic_group
          }else{
            //查询网红是否存在
            const ic_name = videoParam.ic_name || ''
            let ic_info:any = await this.internetCelebrityService.findOne_ByName(ic_name)
            if(!ic_info){
              let addIc = new InternetCelebrity()
              addIc.name = ic_name
              ic_info = await this.internetCelebrityService.create(addIc)
            }
            if(ic_info){
              video.ic_group = ic_info.id
            }
          }
          resolve(await this.videoService.update(video))
        },(err) => {
          reject(new HttpException(err, HttpStatus.OK))
        })
      })
  }

  @Get('/getVideoCount')
  async GetVideoCount(@Query() params, @Request() req) {
    return (await this.videoService.GetVideoCount(10, params.keyword))?.arr
  }

  /**
   * 根据用户查询视频
   * @param params
   * @returns
   */
  @Get('/findAll_Page_By_User')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async findAll_Page_By_User(@Query() params, @Request() req) {
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let token: number = req.headers.token
    //查询用户的wx_user
    let findUser:User = await this.userServices.findOne(token)
    if(!findUser){
      return new HttpException('用户不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    let wx_user = findUser.wx_user
    let ic_list: any = params.ic_list || []
    let account_list: [] = params.account_list || []
    ic_list.push(...account_list)
    ic_list = [...new Set([...ic_list])]
    let skip: number = pageSize * pageIndex
    let notCertified = params.notCertified == 1
    let dataList = await this.videoService.findAll_By_User(skip, pageSize, ic_list, params.keyword, wx_user, params.type, notCertified)
    let list = dataList.data
    let total = dataList.total
    console.log(params,'paramsparams')
    console.log(dataList,'dataListdataList')

    //根据地址获取防盗链地址 RefererKey
    list.map((currentVideo:any) => {
      let oldurl:any = currentVideo.video_url || ''
      let https = 'https://'
      let http = 'http://'
      if(oldurl.indexOf(https) > -1){
        oldurl = oldurl.substring(oldurl.indexOf(https) + https.length)
      }else if(oldurl.indexOf(http) > -1){
        oldurl = oldurl.substring(oldurl.indexOf(http) + http.length)
      }
      oldurl = oldurl.split('/')
      oldurl = oldurl.slice(1,oldurl.length - 1)
      let endTime:string = parseInt((new Date().getTime() / 1000 + video_VideoTimeout).toString()).toString(16)
      let sign = utils.md5(video_RefererKey + '/' + oldurl.join('/') + '/' + endTime)
      if(currentVideo.video_url){
        let newurl = currentVideo.video_url + '?t=' + endTime + '&sign=' + sign
        currentVideo.video_url = newurl
      }
      //所有图片
      let findMultiImg = dataList.multiImg.filter(c => c.video_id === currentVideo.id)
      if(findMultiImg.length > 0){
        currentVideo.multi_img = findMultiImg.map(e => e.img)
      }
    })
    
    await Promise.all(list.map(async (e: any) => {
      let res = await this.redis.get('video_cover:' + e.video_id)
      if(res && utils.isJSON(res)){
        e.video_cover_recommend = JSON.parse(res)
      }
    }))
    return {total: total, data: list}
  }

  /**
   * 后台管理查询全部视频
   * @param params
   * @returns
   */
  @Get('/findAll_Page')
  async findAll_Page(@Query() params) {
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let ic_list: any = params.ic_list
    let skip: number = pageSize * pageIndex
    let list = {video:[],multiImg:[],total:0, pageIndex: 0}, allCount:any = 0
    let keyword = params.keyword || ''
    let mediaCheckType: number = Number(params.mediaCheckType?.toString())
    let isAnswer = params.isAnswer
    switch(params.searchType){
      case 'all':
        list = await this.videoService.findAll(skip, pageSize, keyword, mediaCheckType, isAnswer)
        allCount = list.total
        break;
      case 'original':
        list = await this.videoService.findAll_Original(skip, pageSize, keyword, mediaCheckType, isAnswer, params.notauth, params.video_id)
        allCount = list.total
        break;
      case 'question':
        list = await this.videoService.findAll_Question(skip, pageSize, keyword, mediaCheckType, isAnswer, params.video_id)
        allCount = list.total
        break;
      case 'answer':
        list = await this.videoService.findAll_Answer(skip, pageSize, keyword, mediaCheckType, isAnswer)
        allCount = list.total
        break;
    }

    //根据地址获取防盗链地址 RefererKey
    list.video.map(currentVideo => {
      let oldurl:any = currentVideo.video_url || ''
      let https = 'https://'
      let http = 'http://'
      if(oldurl.indexOf(https) > -1){
        oldurl = oldurl.substring(oldurl.indexOf(https) + https.length)
      }else if(oldurl.indexOf(http) > -1){
        oldurl = oldurl.substring(oldurl.indexOf(http) + http.length)
      }
      oldurl = oldurl.split('/')
      oldurl = oldurl.slice(1,oldurl.length - 1)
      let endTime:string = parseInt((new Date().getTime() / 1000 + video_VideoTimeout).toString()).toString(16)
      let sign = utils.md5(video_RefererKey + '/' + oldurl.join('/') + '/' + endTime)
      if(currentVideo.video_url){
        let newurl = currentVideo.video_url + '?t=' + endTime + '&sign=' + sign
        currentVideo.video_url = newurl
      }

      //所有图片
      let findMultiImg = list.multiImg.filter(c => c.video_id === currentVideo.id)
      if(findMultiImg.length > 0){
        currentVideo.multi_img = findMultiImg.filter(e => e.multi_img || e.img).map(e => e.multi_img || e.img)
      }
    })

    let videos = list.video
    await Promise.all(videos.map(async e => {
      let res = await this.redis.get('video_cover:' + e.video_id)
      if(res && utils.isJSON(res)){
        e.video_cover_recommend = JSON.parse(res)
      }
    }))

    return {total: allCount, data: videos, pageIndex: list.pageIndex}
  }

  /**
   * 后台管理删除视频
   * @param params
   * @returns
   */
  @Post('/remove_auth')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async remove_auth(@Body() params: { id: number }){
    let findOne = await this.videoService.findOne(params.id)
    let err = await this.videoService.remove_video_library(params.id)
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return new Promise((resolve,reject) => {
        this.deleteVideo(findOne.video_id,(data) => {
          resolve(true)
        },(err) => {
          reject(new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR))
        })
      })
    }
  }

  /**
   * 后台管理删除视频
   * @param params
   * @returns
   */
  @Post('/remove')
  async remove(@Body() params: { id: number }){
    let findOne = await this.videoService.findOne(params.id)
    let err = await this.videoService.remove_video_library_manager(params.id)
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return new Promise((resolve,reject) => {
        this.deleteVideo(findOne.video_id,(data) => {
          resolve(true)
        },(err) => {
          reject(new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR))
        })
      })
    }
  }

  /**
   * 删除云点播资源
   * @param FileId
   * @param then
   * @param catchF
   */
  deleteVideo(FileId: string, then: Function, catchF: Function){
    const client = new VodClient(clientConfig);
    const params = {
      "FileId": FileId,
      "SubAppId": video_SubAppId
    };
    client.DeleteMedia(params).then(
      (data) => {
        then(data)
      },
      (err) => {
        catchF(err)
      }
    );
  }

  //微信端api--------------------------------------
  @Post('uploadCover')
  @UseInterceptors(FileInterceptor('pic'))
  addUser(@UploadedFile() file,@Body() body){
    const writeImage = createWriteStream(join(__dirname, '..','../public/upload', `${file.originalname}`))
    writeImage.write(file.buffer)
    return '上传成功';
  }


  /**
   * 根据视频id模糊搜索
   * @param params
   * @param req
   * @returns
   */
  @Get("findAll_Like_Id")
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findAll_Like_Id(@Query() params, @Request() req) {
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let skip: number = pageSize * pageIndex
    return await this.videoService.findAll_Like_Id(skip, pageSize, req.headers.wx_user, params.id, params.type === 'question')
  }

  
  /**
   * 查询我的作品(一个视频)
   * @param params
   * @param req
   * @returns
   */
  @Get('/findOne_MyOriginal')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findOne_MyOriginal(@Query() params, @Request() req) {
    let wx_user = req.headers.wx_user
    //查询是海外还是国内
    let overseas = 0
    let findOverseas = await this.userSettingServices.findOne_by_key(wx_user, 'overseas')
    if(findOverseas){
      overseas = findOverseas.value == "1" ? 1 : 3
    }
    let dataList: any = await this.videoService.findOne_MyOriginal(params.video_id, wx_user, params.searchType, overseas)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg)
    if(dataList.data.length > 0){
      return dataList.data[0]
    }else{
      return undefined
    }
  }

  /**
   * 查询我的作品
   * @param params
   * @param req
   * @returns
   */
  @Get('/findAll_MyOriginal')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findAll_MyOriginal(@Query() params, @Request() req) {
    let wx_user = req.headers.wx_user
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let skip: number = pageSize * pageIndex
    //查询是海外还是国内
    let overseas = 0
    let findOverseas = await this.userSettingServices.findOne_by_key(wx_user, 'overseas')
    if(findOverseas){
      overseas = findOverseas.value == "1" ? 1 : 3
    }
    //查询看答案的作品开关是否已打开
    let getSwitch:Setting = await this.settingServices.findOne_by_key(SettingKeyEnum.switch_view_answer_works)
    let isOpen: boolean = Number(!getSwitch ? 1 : getSwitch?.value) == 1
    let dataList = await this.videoService.findAll_MyOriginal(skip, pageSize, wx_user, params.searchType, overseas)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg)
    let total = await this.videoService.findAll_MyWorksTotal(wx_user)

    return {data:dataList.data, total: total}
  }
  
  /**
   * 查询我的回答（一个视频）
   * @param params
   * @param req
   * @returns
   */
  @Get('/findOne_MyAnswer')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findOne_MyAnswer(@Query() params, @Request() req) {
    let wx_user = req.headers.wx_user
    let dataList: any = await this.videoService.findOne_MyAnswer(params.video_id, wx_user)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg)
    if(dataList.data.length > 0){
      return dataList.data[0]
    }else{
      return undefined
    }
  }

  /**
   * 查询我的回答
   * @param params
   * @param req
   * @returns
   */
  @Get('/findAll_MyAnswer')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findAll_MyAnswer(@Query() params, @Request() req) {
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let skip: number = pageSize * pageIndex
    let wx_user = req.headers.wx_user
    let dataList = await this.videoService.findAll_MyAnswer(skip, pageSize, wx_user)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg)
    let total = await this.videoService.findAll_MyWorksTotal(wx_user)
    return {data:dataList.data, total: total}
  }

  /**
   * 查询我的提问所在页码
   * @param params
   * @param req
   * @returns
   */
  @Get('/findAll_MyWorksTotal_PageIndex')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findAll_MyWorksTotal_PageIndex(@Query() params, @Request() req) {
    let wx_user = req.headers.wx_user
    let pageIndex = await this.videoService.findAll_MyWorksTotal_PageIndex(params.video_id, params.pageSize, wx_user, params.type)
    return pageIndex
  }

  /**
   * 查询我的提问
   * @param params
   * @param req
   * @returns
   */
  @Get('/findAll_MyQuestioin')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findAll_MyQuestioin(@Query() params, @Request() req) {
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let skip: number = pageSize * pageIndex
    let wx_user = req.headers.wx_user
    let dataList = await this.videoService.findAll_MyQuestioin(skip, pageSize, wx_user)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg, dataList.rewardAnswerList)
    let total = await this.videoService.findAll_MyWorksTotal(wx_user)

    return {data:dataList.data, total: total}
  }

  /**
   * 查询我的提问(一个视频)
   * @param params
   * @param req
   * @returns
   */
  @Get('/findOne_MyQuestioin')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findOne_MyQuestioin(@Query() params, @Request() req) {
    let wx_user = req.headers.wx_user
    let dataList: any = await this.videoService.findOne_MyQuestioin(params.video_id, wx_user)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg, dataList.rewardAnswerList)
    if(dataList.data.length > 0){
      return dataList.data[0]
    }else{
      return undefined
    }
  }

  
  /**
   * 查询我的提问(一个视频)
   * @param params
   * @param req
   * @returns
   */
  @Get('/findOne_Collection')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findOne_Collection(@Query() params, @Request() req) {
    let wx_user = req.headers.wx_user
    let dataList: any = await this.videoService.findOne_Collection(params.video_id, wx_user)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg, dataList.rewardAnswerList)
    if(dataList.data.length > 0){
      return dataList.data[0]
    }else{
      return undefined
    }
  }

  /**
   * 查询收藏视频
   * @param params
   * @param req
   * @returns
   */
  @Get('/findAll_Collection')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findAll_Collection(@Query() params, @Request() req) {
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let skip: number = pageSize * pageIndex
    let wx_user = req.headers.wx_user
    let dataList = await this.videoService.findAll_Collection(skip, pageSize, wx_user)
    dataList.data.map(e => {
      this.getPlayVideoUrl(e)
    })
    this.setVideoAnswer(wx_user, dataList.data, dataList.answer, dataList.multiImg)
    let total = await this.videoService.findAll_MyWorksTotal(wx_user)
    return {data:dataList.data, total: total}
  }

  @Get('/findAll_MyWorksTotal')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  findAll_MyWorksTotal(@Query() params, @Request() req){
    return this.videoService.findAll_MyWorksTotal(req.headers.wx_user)
  }

  /**
   * 根据视频key查询视频
   * @param params
   * @param req
   * @returns
   */
  @Get('/getVideo_by_video_key')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async getVideo_by_video_key(@Query() params, @Request() req) {
    let wx_user: string = req.headers.wx_user
    
    let main = params.main
    if(main !== undefined && typeof(main) === 'string'){
      if(main === 'false'){
        main = false
      }else if(main === 'true'){
        main = true
      }
    }
    let list = await this.videoService.findOne_By_Video_id(params.video_id, wx_user, params.uid, params.shareuid, params.original, params.level, params.source, main, params.not_answer)
    list.video.map((e: any) => {
      for(let key in e){
        if(e[key] === null || e[key] === undefined){
          delete e[key]
        }
      }
    })

    this.setVideoAnswer(wx_user, list.video, list.answer, list.multiImg)
    //设置redis
    let keyIc = 'videos:'
    // await Promise.all(list.video.map(async (findVideoBasic: any) => {
    //   //个人消费数据
    //   let profitData: any = {}
    //   for(let key in findVideoBasic){
    //     if(video_basic.indexOf(key) === -1){
    //       profitData[key] = findVideoBasic[key]
    //     }
    //   }
    //   let fk = keyIc + findVideoBasic.id + ':'
    //   delete profitData.not_profit
    //   delete profitData.workSource
    //   await this.redisCacheService.set(fk + "profit:" + wx_user, profitData)
    // }))
    //设置redis
    await Promise.all(list.video.map(async (findVideoBasic: any) => {
      delete findVideoBasic.basic
      let fk = keyIc + findVideoBasic.id + ':'
      let data = {}
      video_basic.map(k => {
        data[k] = findVideoBasic[k]
      })
      await this.redisCacheService.set(fk + 'basic', data)
    }))

    list.video.map(currentVideo => {
      this.getPlayVideoUrl(currentVideo)
    })
    return list.video
  }

  /**
   * 获取视频列表
   * @param params
   * @param req
   * @returns
   */
  @Get('/getVideo_by_video_id_list')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async getVideo_by_video_id_list(@Query() params, @Request() req) {
    let wx_user: string = req.headers.wx_user
    let { take, skip } = utils.getLimit(params.pageSize, params.pageIndex)
    let video_id_list = params.video_id_list || ''
    video_id_list = video_id_list.split(',')
    let list:any = await this.videoService.findOne_By_Video_Id_List(video_id_list, wx_user)
    this.setVideoAnswer(wx_user, list.video, list.answer, list.multiImg)
    list.video.map(currentVideo => {
      this.getPlayVideoUrl(currentVideo)
    })
    return list.video
  }

  /**
   * 获取防盗链视频链接
   * @param currentVideo
   */
  getPlayVideoUrl(currentVideo){
    let oldurl:any = currentVideo.video_url || ''
    let https = 'https://'
    let http = 'http://'
    if(oldurl.indexOf(https) > -1){
      oldurl = oldurl.substring(oldurl.indexOf(https) + https.length)
    }else if(oldurl.indexOf(http) > -1){
      oldurl = oldurl.substring(oldurl.indexOf(http) + http.length)
    }
    oldurl = oldurl.split('/')
    oldurl = oldurl.slice(1,oldurl.length - 1)
    let endTime:string = parseInt((new Date().getTime() / 1000 + video_VideoTimeout).toString()).toString(16)
    let sign = utils.md5(video_RefererKey + '/' + oldurl.join('/') + '/' + endTime)
    if(currentVideo.video_url){
      let newurl = currentVideo.video_url + '?t=' + endTime + '&sign=' + sign
      currentVideo.video_url = newurl
    }
  }

  /**
   * 修改视频封面图
   */
  uploadVideoCover(video_id: string, video_cover: string): Promise<string>{
    return new Promise((resolve,reject) => {
      const params = {
        FileId:video_id,
        CoverData:video_cover,
        SubAppId: video_SubAppId
      };
      const client = new VodClient(clientConfig);
      client.ModifyMediaInfo(params).then(
        (data) => {
          resolve(data.CoverUrl)
        },
        (err) => {
          resolve('')
        }
      );
    })
  }

  /**
   * 微信上传视频
   * @param videoParam
   * @param req
   * @returns
   */
  @Post('/client_upload_video')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async client_upload_video(@Body() videoParam: { platformList: [], ic_group:number, multi_img:MultiImg[], profit_type: number, title: string; desc: string, type: number, isreward?: number, video_url?: string, video_ratio?: string, video_cover?: string, fileId?: string, original?: boolean }, @Request() req) {
    const wx_user = req.headers.wx_user
    //查询是否打开了海外作者素材入口
    let isOverseas = false
    let findOverseas = await this.userSettingServices.findOne_by_key(wx_user, 'overseas')
    if(findOverseas){
      isOverseas = Number(findOverseas.value) == 0 ? false : true
    }
    //非认证用户上传视频清空ic_group
    if(!isOverseas){
      delete videoParam.ic_group
    }

    //查询用户信息
    let findUserInfo:WxUser = await this.wxUserServices.findOne_By_OpenId(wx_appid,wx_user)
    findUserInfo = findUserInfo[0]
    let wx_app_openid = findUserInfo.wx_app_openid
    const video = new Video();
    video.title = videoParam.title;
    video.desc = videoParam.desc;
    video.video_ratio = videoParam.video_ratio
    video.create_time = new Date();
    video.update_time = new Date();
    video.video_id = videoParam.fileId;
    video.video_url = videoParam.video_url;
    video.video_cover = videoParam.video_cover;
    video.check = 0
    video.type = videoParam.type
    video.wx_user = wx_user
    video.overseas = isOverseas ? OverseasEnum.yes : OverseasEnum.virtual
    if(videoParam.isreward === IsRewardEnum.yes){
      video.isreward = IsRewardEnum.yes
    }else if(videoParam.isreward == IsRewardEnum.big){
      video.isreward = IsRewardEnum.big
    }
    if(videoParam.original){
      video.original = OriginalEnum.yes
      video.ic_group = videoParam.ic_group
      if(videoParam.profit_type == 2){
        video.profit_type = 1
        video.look_video_and_answer = 1
      }else{
        video.profit_type = videoParam.profit_type
      }
    }else{
      video.original = OriginalEnum.no
      video.is_home = EnumIsHome.no
      video.profit_type = ProfitTypeEnum.answer
    }

    let traceRelaTableList:TraceRelaTable[] = []
    let mediaCheckError = false
    const wxapi = new WXAPI()
    let ish5 = wx_user.substring(0,2) === 'h5' && wx_user.length === 22
    //上传视频封面
    if(video.type === VideoEnum.video){
      if(!ish5){
        video.video_cover = await this.uploadVideoCover(video.video_id, video.video_cover)
      }
    }else{
      if(!ish5){
        //验证缩略图
        let result:any = await wxapi.mediaCheckAsync(video.video_cover, wx_app_openid)
        if(result?.trace_id){
          video.trace_id = result.trace_id
          //创建任务、表关联
          let addTrace = new TraceRelaTable()
          addTrace.trace_id = result.trace_id
          addTrace.table = 'video'
          addTrace.create_time = new Date()
          traceRelaTableList.push(addTrace)
        }else{
          return new HttpException('审核图片失败，请重新发布', HttpStatus.INTERNAL_SERVER_ERROR)
        }
      }
      //验证多图
      if(videoParam.multi_img?.length > 1){
        let valid_multi_img = () => {
          return new Promise((resolve,reject) => {
            let multi_img_list = videoParam.multi_img.slice(1)
            let multi_img_len = multi_img_list.length
            multi_img_list.map(async (e:MultiImg) => {
              if(!mediaCheckError && !ish5){
                let check_result:any = await wxapi.mediaCheckAsync(e.img, wx_app_openid)
                if(check_result?.trace_id){
                  e.trace_id = check_result.trace_id
                  //创建任务、表关联
                  let addTrace = new TraceRelaTable()
                  addTrace.trace_id = check_result.trace_id
                  addTrace.table = 'multi_img'
                  addTrace.create_time = new Date()
                  traceRelaTableList.push(addTrace)
                }else{
                  mediaCheckError = true
                }
              }
              multi_img_len--
              if(multi_img_len == 0){
                resolve(true)
              }
            })
          })
        }
        await valid_multi_img()
      }
    }
    if(mediaCheckError){
      return new HttpException('审核图片失败，请重新发布', HttpStatus.INTERNAL_SERVER_ERROR)
    }
    //所有答案
    let findPlatformList = []
    // if(video.profit_type === ProfitTypeEnum.works){
    //   findPlatformList = []
    // }else{
    //查询所有平台
    //未认证
    if(!isOverseas){
      findPlatformList = (videoParam.platformList || []).filter((e: any) => e.platform)
    }else{
      findPlatformList = await this.platformServices.findAll_By_Wx_User(wx_user,TypeEnumPlatform.overseas)
    }
    // }

    let answerList:AnswerInfo[] = []
    let findPlatformList_Len = findPlatformList.length
    let valid_answer_img = () => {
      return new Promise((resolve, reject) => {
        findPlatformList.map(async e => {
          if(!mediaCheckError && !ish5){
            let addAnswerInfo = new AnswerInfo()
            addAnswerInfo.platform = e.platform
            addAnswerInfo.ic_name = e.ic_name
            addAnswerInfo.img = e.img
            addAnswerInfo.img_id = e.img_id
            addAnswerInfo.account = e.account
            addAnswerInfo.avatar_id = e.avatar_id
            addAnswerInfo.avatar_img = e.avatar_img
            answerList.push(addAnswerInfo)
            if(e.img){
              let check_result:any = await wxapi.mediaCheckAsync(e.img, wx_app_openid)
              if(check_result?.trace_id){
                addAnswerInfo.trace_id = check_result.trace_id
                //创建任务、表关联
                let addTrace = new TraceRelaTable()
                addTrace.trace_id = check_result.trace_id
                addTrace.table = 'answer_info'
                addTrace.create_time = new Date()
                traceRelaTableList.push(addTrace)
              }else{
                mediaCheckError = true
              }
            }
          }
          findPlatformList_Len--
          if(findPlatformList_Len === 0){
            resolve(true)
          }
        })
      })
    }
    if(findPlatformList_Len > 0){
      await valid_answer_img()
    }
    
    if(mediaCheckError){
      return new HttpException('审核图片失败，请重新发布', HttpStatus.INTERNAL_SERVER_ERROR)
    }
    
    let result = await this.videoService.client_upload_video(wx_user, video, videoParam.multi_img, answerList, traceRelaTableList, isOverseas)
    let err = result.error
    console.log(err,'error')
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return result.result
    }
  }

  /**
   * 设置视频答案
   * @param wx_user
   * @param videoList
   */
  async setVideoAnswer(wx_user: string, videoList: any, answerList: any, multiImg: any, rewardAnswerList?: any, videos?: any[]){
    rewardAnswerList = rewardAnswerList || []
    videoList.map((e:any) => {
      if(videos){
        let findV = videos.findIndex(c => c.id == e.id)
        if(findV > -1){
          e = videos[findV]
        }
      }
      let findAnswerList = answerList.filter(c => c.video_id == e.id)
      //视频审核通过的答案编号
      let findOKAnswher = findAnswerList.find(c => c.check == 1)
      e.check_answer = findOKAnswher?.answer_id
      //是否有驳回的答案
      if(!e.check_answer && findAnswerList.find(c => utils.judeAnswerIsReject(c))){
        e.check_answer = 0
      }
      if(!e.check_answer && e.ic_group){
        e.check_answer = -1
      }
      //审核中的答案
      e.is_answer = findAnswerList.find(c => c.check != 1 && c.check !== 0 && c.wx_user == wx_user)?.wx_user
      //自己的所有答案
      e.is_answer_history = findAnswerList.find(c => c.wx_user == wx_user && !(c.type == 2 && c.check == 0)) ? true : false
      if(e.is_answer_history && e.original == 0 && findAnswerList.find(c => c.check == 1 && c.wx_user == e.video_author && c.wx_user == wx_user)){
        e.is_answer_history = false
      }
      //自己回答审核通过，或者自己产生利润（返回答案）
      let findAnswerResult = findAnswerList.filter(c => c.check == 1 && (c.wx_user == wx_user || (c.profit_status != profitEnum.refoundSuccess && c.answer_id && c.use_wx_user == wx_user)))
      console.log(findAnswerResult, '----findAnswerList=>', findAnswerList)
      if(findAnswerResult.length > 0){
        e.is_profit_result = true
      }
      //答案作者是我自己
      if(findAnswerList.find(c => c.check == 1 && c.wx_user == wx_user)){
        e.answer_author_is_me = true
      }else{
        //答案是否被驳回
        //1、不存在审核中
        //2、被拒绝
        let now = new Date().getTime()
        if(!e.is_answer && findAnswerList.find(c => (c.check == 0) && c.wx_user === wx_user)){
          e.answer_is_me_reject = true
        }
      }
      //自己回答审核通过，或者自己产生利润（返回多图）
      e.multi_img = multiImg.filter(c => c.video_id == e.id && ((c.check == 1 && c.wx_user == wx_user) || (c.answer_id && c.use_wx_user == wx_user)) && c.multi_img).map(c => c.multi_img)
      if(e.multi_img.length === 0){
        delete e.multi_img
      }
      // e.multi_img_count = multiImg.filter(c => c.video_id == e.id).length

      let findProfit = findAnswerList.find(c => (c.check == 1 && c.wx_user == wx_user) || (c.answer_id && c.use_wx_user == wx_user && (c.profit_status == 0 || c.profit_status == 1 || c.profit_status == 3)))
      e.profit_works = findProfit?.id
      e.profit_status = findProfit?.profit_status
      if(e.video_author == wx_user){
        e.author = true
      }
      e.author_answer = findAnswerList.find(e => e.wx_user == wx_user && e.type != 2) ? true : false
      if(e.video_author === system_wx_user && e.video_author === wx_user){
        e.system_wx_user = true
      }
      if(wx_user === system_wx_user){
        e.is_system_user = true
      }
      delete e.video_author
      //悬赏的作品有答案了
      if(rewardAnswerList.find(c => c.wx_user == wx_user && c.video_id == e.id)){
        e.rewardIsAnswer = true
      }
      if(e.wx_user_source === wx_user){
        e.author_source = true
      }
      delete e.wx_user_source
    })
  }

  /**
   * 微信查询所有视频
   * @param params
   * @param req
   * @returns
   */
  @Post('/findAll')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findAll(@Body() params, @Request() req) {
    let wx_user: string = req.headers.wx_user
    let pageSize: number = parseInt(params.pageSize)
    let pageIndex: number = parseInt(params.pageIndex)
    let ids = (params.loadedIds||'').split(',').filter(e => e)
    let ics = (params.loadedIcs||'').split(',').filter(e => e)

    let ids_source = (params.loadedIds||'').split(',').filter(e => e)
    let ics_source = (params.loadedIcs||'').split(',').filter(e => e)

    let result:any = await this.videoService.findAll_Forent_Yes_Answer_New(pageSize, pageIndex, wx_user, params.loadType, undefined, ids, ics, params.commend)
    let videos = result.video
    let list = videos

    if(list.length === 0 && params.loadType !== 'video'){
      result = await this.videoService.findUserLastVideo(wx_user, params.loadType)
      videos = result.video
      list = videos
    }
    this.setVideoAnswer(wx_user, videos, result.answer, result.multiImg, undefined, videos)
    list = list.filter(e => e)
    list.map(e => {
      for(let key in e){
        if(e[key] === null || e[key] === undefined){
          delete e[key]
        }
      }
    })
    
    let keyIc = 'videos:'
    await Promise.all(list.filter(e => !e.basic).map(async findVideoBasic => {
      delete findVideoBasic.basic
      let fk = keyIc + findVideoBasic.id + ':'
      let keys = video_basic
      let data = {}
      keys.map(k => {
        data[k] = findVideoBasic[k]
      })
      await this.redisCacheService.set(fk + 'basic', data)
    }))
    //写入同提问数据
    await Promise.all(list.map(async (e: any) => {
      await this.redisCacheService.set(`videos:${e.id}:question:${wx_user}`, e.isQuestion == 1 || e.isQuestion == true)
      await this.redisCacheService.set(`videos:${e.id}:questioncount`, e.question_count || 0)
    }))

     //根据地址获取防盗链地址 RefererKey
     list.map(currentVideo => {
      this.getPlayVideoUrl(currentVideo)
    })
    return {list: list, pageIndex:result.pageIndex, ids: ids_source, ics: ics_source}
  }
  
  /**
   * 微信端删除视频
   * @param data 
   * @param req 
   * @returns 
   */
  @Post('/delete')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async delete(@Body() data, @Request() req){
    let deleteYunRes = utils.deleteYunRes
    let err = await this.videoService.delete(data.video_id, req.headers.wx_user, deleteYunRes)
    console.log(err,'rr')
    if(err){
      return new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR)
    }else{
      return true
    }
  }

  /**
   * 删除自己的提问
   * @param data 
   * @param req 
   * @returns 
   */
  @Post('/delete_my_question')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async delete_my_question(@Body() data, @Request() req){
    let result = await this.videoService.delete_my_question(data.video_id, req.headers.wx_user)
    if(result.success){
      return true
    }else{
      return new HttpException(result.msg, HttpStatus.INTERNAL_SERVER_ERROR)
    }
  }

  @Post('/deleteYunVideo')
  async deleteYunVideo(@Body() data){
    return await utils.deleteYunRes(data.fileId, video_SubAppId)
  }

  @Post('/changeIsHome')
  @UseInterceptors(ValidUniqueLoginInterceptor)
  async changeIsHome(@Body() data, @Request() req){
    let token: number = req.headers.token
    //查询用户的wx_user
    let findUser:User = await this.userServices.findOne(token)
    if(!findUser){
      return new HttpException('用户不存在',HttpStatus.INTERNAL_SERVER_ERROR)
    }
    return this.videoService.changeIsHome(data.id, data.is_home)
  }

  
  @Post('/findIcVideos')
  @UseInterceptors(ValidTokenInterceptor)
  @UseInterceptors(ValidRSAInterceptor)
  async findIcVideos(@Body() params, @Request() req){
    let wx_user = req.headers.wx_user
    let dataList = [], multiImg = [], answerList = []
    let keyIc = 'videos:'
    let profits = []
    //查询没有基础数据的收益更新
    await Promise.all(params.profits.map(async e => {
      if(!params.basics.find(c => c == e)){
        let fk = keyIc + e + ':'
        let basic = await this.redisCacheService.get(fk + 'basic')
        if(!basic){
          params.basics.push(e)
        }else{
          profits.push(e) 
        }
      }
    }))
    if(params.basics.length > 0){
      let result = await this.videoService.findIcVideos(wx_user, params.basics || [])
      dataList = result.dataList
      multiImg = result.multiImg
      answerList = result.answerList
    

      this.setVideoAnswer(wx_user, dataList, answerList, multiImg)
      dataList = dataList.filter(e => e)
      dataList.map(e => {
        for(let key in e){
          if(e[key] === null || e[key] === undefined){
            delete e[key]
          }
        }
      })
      await Promise.all(dataList.map(async findVideoBasic => {
        let fk = keyIc + findVideoBasic.id + ':'
        let keys = video_basic
        let data = {}
        keys.map(k => {
          data[k] = findVideoBasic[k]
        })
        await this.redisCacheService.set(fk + 'basic', data)

        //个人消费数据
        let profitData: any = {}
        for(let key in findVideoBasic){
          if(keys.indexOf(key) === -1){
            profitData[key] = findVideoBasic[key]
          }
        }
        delete profitData.workSource
        delete profitData.not_profit
        await this.redisCacheService.set(fk + "profit:" + wx_user, profitData)
      }))
    }
    if(profits.length > 0){
      let result = await this.videoService.findIcVideos(wx_user, profits || [])
      let dataListProfit = result.dataList
      let multiImg = result.multiImg
      let answerList = result.answerList
      this.setVideoAnswer(wx_user, dataListProfit, answerList, multiImg)
      dataListProfit = dataListProfit.filter(e => e)
      dataListProfit.map(e => {
        for(let key in e){
          if(e[key] === null || e[key] === undefined){
            delete e[key]
          }
        }
      })
      await Promise.all(dataListProfit.map(async findVideoBasic => {
        let keys = video_basic
        //个人消费数据
        let profitData: any = {}
        for(let key in findVideoBasic){
          if(keys.indexOf(key) === -1){
            profitData[key] = findVideoBasic[key]
          }
        }
        delete profitData.workSource
        delete profitData.not_profit
        let fk = keyIc + findVideoBasic.id + ':'
        await this.redisCacheService.set(fk + "profit:" + wx_user, profitData)
      }))
      dataList.push(...dataListProfit)
    }
    //更新
    dataList.map(e => {
      this.getPlayVideoUrl(e)
    })
    return {videos: dataList}
  }
}
